xentrace: trace power management events.
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 16 Oct 2008 08:51:42 +0000 (09:51 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 16 Oct 2008 08:51:42 +0000 (09:51 +0100)
Signed-off-by: Guanqun Lu <guanqun.lu@intel.com>
tools/xentrace/formats
xen/arch/x86/acpi/cpu_idle.c
xen/drivers/cpufreq/utility.c
xen/include/public/trace.h

index 84d8cc68416565070e2398a812083d09606766ee..5d84eec6b3cafa33d080403d9d56b557c557754f 100644 (file)
 0x0040f10e  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  shadow_emulate_resync_full        [ gfn = 0x%(1)16x ]
 0x0040f00f  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  shadow_emulate_resync_only        [ gfn = 0x%(1)08x ]
 0x0040f10f  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  shadow_emulate_resync_only        [ gfn = 0x%(1)16x ]
+
+0x00801001  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  cpu_freq_change [ %(1)dMHz -> %(2)dMHz ]
+0x00802001  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  cpu_idle_entry  [ C0 -> C%(1)d ]
+0x00802002  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  cpu_idle_exit   [ C%(1)d -> C0 ]
index 8d2aa88d41e143f465a99087dce0bb11b06d6ec8..176129489e598410f8bbb5f2d7e592da3adc5a3d 100644 (file)
@@ -40,6 +40,7 @@
 #include <xen/guest_access.h>
 #include <xen/keyhandler.h>
 #include <xen/cpuidle.h>
+#include <xen/trace.h>
 #include <asm/cache.h>
 #include <asm/io.h>
 #include <asm/hpet.h>
@@ -251,6 +252,9 @@ static void acpi_processor_idle(void)
     switch ( cx->type )
     {
     case ACPI_STATE_C1:
+        /* Trace cpu idle entry */
+        TRACE_1D(TRC_PM_IDLE_ENTRY, 1);
+
         /*
          * Invoke C1.
          * Use the appropriate idle routine, the one that would
@@ -261,6 +265,9 @@ static void acpi_processor_idle(void)
         else 
             acpi_safe_halt();
 
+        /* Trace cpu idle exit */
+        TRACE_1D(TRC_PM_IDLE_EXIT, 1);
+
         /*
          * TBD: Can't get time duration while in C1, as resumes
          *      go to an ISR rather than here.  Need to instrument
@@ -272,12 +279,16 @@ static void acpi_processor_idle(void)
     case ACPI_STATE_C2:
         if ( local_apic_timer_c2_ok )
         {
+            /* Trace cpu idle entry */
+            TRACE_1D(TRC_PM_IDLE_ENTRY, 2);
             /* Get start time (ticks) */
             t1 = inl(pmtmr_ioport);
             /* Invoke C2 */
             acpi_idle_do_entry(cx);
             /* Get end time (ticks) */
             t2 = inl(pmtmr_ioport);
+            /* Trace cpu idle exit */
+            TRACE_1D(TRC_PM_IDLE_EXIT, 2);
 
             /* Re-enable interrupts */
             local_irq_enable();
@@ -316,6 +327,8 @@ static void acpi_processor_idle(void)
             ACPI_FLUSH_CPU_CACHE();
         }
 
+        /* Trace cpu idle entry */
+        TRACE_1D(TRC_PM_IDLE_ENTRY, cx - &power->states[0]);
         /*
          * Before invoking C3, be aware that TSC/APIC timer may be 
          * stopped by H/W. Without carefully handling of TSC/APIC stop issues,
@@ -335,6 +348,8 @@ static void acpi_processor_idle(void)
 
         /* recovering TSC */
         cstate_restore_tsc();
+        /* Trace cpu idle exit */
+        TRACE_1D(TRC_PM_IDLE_EXIT, cx - &power->states[0]);
 
         if ( power->flags.bm_check && power->flags.bm_control )
         {
index 882a7cc4526eeeff830c982bd509a36eb3a65778..a26e2518c35d419c87f051fc20ccb264a9abada1 100644 (file)
@@ -27,6 +27,7 @@
 #include <xen/types.h>
 #include <xen/sched.h>
 #include <xen/timer.h>
+#include <xen/trace.h>
 #include <asm/config.h>
 #include <acpi/cpufreq/cpufreq.h>
 #include <public/sysctl.h>
@@ -293,7 +294,13 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
     int retval = -EINVAL;
 
     if (cpu_online(policy->cpu) && cpufreq_driver->target)
+    {
+        unsigned int prev_freq = policy->cur;
+
         retval = cpufreq_driver->target(policy, target_freq, relation);
+        if ( retval == 0 )
+            TRACE_2D(TRC_PM_FREQ_CHANGE, prev_freq/1000, policy->cur/1000);
+    }
 
     return retval;
 }
index a11b30f32cf064b2ceceac6056dffb9be7fa7ad4..5cce0287ebf75c2a2a2615cc5efb8451054afbee 100644 (file)
@@ -38,6 +38,7 @@
 #define TRC_MEM      0x0010f000    /* Xen memory trace         */
 #define TRC_PV       0x0020f000    /* Xen PV traces            */
 #define TRC_SHADOW   0x0040f000    /* Xen shadow tracing       */
+#define TRC_PM       0x0080f000    /* Xen power management trace */
 #define TRC_ALL      0x0ffff000
 #define TRC_HD_TO_EVENT(x) ((x)&0x0fffffff)
 #define TRC_HD_CYCLE_FLAG (1UL<<31)
 #define TRC_HVM_LMSW            (TRC_HVM_HANDLER + 0x19)
 #define TRC_HVM_LMSW64          (TRC_HVM_HANDLER + TRC_64_FLAG + 0x19)
 
+/* trace subclasses for power management */
+#define TRC_PM_FREQ     0x00801000      /* xen cpu freq events */
+#define TRC_PM_IDLE     0x00802000      /* xen cpu idle events */
+
+/* trace events for per class */
+#define TRC_PM_FREQ_CHANGE      (TRC_PM_FREQ + 0x01)
+#define TRC_PM_IDLE_ENTRY       (TRC_PM_IDLE + 0x01)
+#define TRC_PM_IDLE_EXIT        (TRC_PM_IDLE + 0x02)
+
 /* This structure represents a single trace buffer record. */
 struct t_rec {
     uint32_t event:28;